// @ts-check
"use strict";

require("dotenv/config");

const path = require("node:path");
const process = require("node:process");

// const { DotenvRunPlugin } = require("@dotenv-run/webpack");
// const { AngularWebpackPlugin } = require("@ngtools/webpack");
// const HtmlBundlerPlugin = require("html-bundler-webpack-plugin");
// const WebpackBundleTracker = require("webpack-bundle-tracker");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
// eslint-disable-next-line jsdoc/no-restricted-syntax
/** @type {any} */
const preprocessorDirectives = require("unplugin-preprocessor-directives/webpack");
const turboConsole = require("unplugin-turbo-console/webpack").default;
const { ManifestPlugin, ProgressPlugin } = require("webpack");
const { pwd2 } = require("./alias-kit.js");
const {
  HtmlWebpackPatchPlugin,
} = require("./rspack/plugin/HtmlRspackPatchPlugin.cjs");
const {
  WrapperProgressivePlugin,
} = require("./rspack/plugin/WrapperProgressivePlugin.cjs");
const { devServerConfig } = require("./xpack.shared.config.cjs");

const isDevelopment = process.env.NODE_ENV !== "production";

/** @type {import('webpack').Configuration} */
module.exports = {
  .../** @type {import('webpack').Configuration} */ (devServerConfig),
  entry: {
    // ngxApp: {
    //   filename: "ngx-app.[contenthash:8].js",
    //   import: [pwd2("./app/ngx-app/src/bootstrap.bybrid.ts")],
    //   layer: "ngx-app-layer",
    //   chunkLoading: "import",
    // },
    main: {
      // layer: "app-main",
      filename: "main.[contenthash:8].js",
      import: [
        // only middleware
        // isDevelopment ? fg.globSync("@rspack/core/hot/*").map(m => require.resolve(m)) : false,
        // isDevelopment
        //   ? require.resolve("@rspack/dev-server/client/index.js?hot=true&live-reload=true")
        //   : false,

        // pwd2("./src/override-var.less"),
        // require.resolve("bootstrap/dist/css/bootstrap.css"),
        // require.resolve("bootstrap/dist/css/bootstrap-theme.css"),
        // require.resolve("angular-ui-bootstrap/dist/ui-bootstrap-csp.css"),
        // require.resolve("angular/angular-csp.css"),
        // pwd2("./src/main.css"),
        // pwd2("./src/tw.css"),
        pwd2("./src/index.mjs"),
        pwd2("./src/main.css"),
        // pwd2("./src/view/DeveloperGuide/NgUIBootstrap/uib.less"),
      ]
        // .flat(2)
        .filter((i) => typeof i === "string"),
      asyncChunks: true,
      chunkLoading: "import",
      dependOn: ["ng", "ng-module"],
    },
    prelude: {
      import: [pwd2("./prelude/index.js")],
      library: {
        type: "window",
      },
      layer: "prelude-layer",
      chunkLoading: "jsonp",
    },
    jquery: {
      filename: "jquery.[contenthash:8].js",
      import: [
        !isDevelopment
          ? require.resolve("jquery/dist/jquery.min.js")
          : require.resolve("jquery"),
      ],
      library: {
        type: "window",
      },
      dependOn: ["prelude"],
      layer: "ng-layer",
      chunkLoading: "import",
    },
    ng: {
      filename: "angular.[contenthash:8].js",
      import: [
        // !isDevelopment
        //   ? require.resolve("angular-loader/angular-loader.min.js")
        //   :
        require.resolve("angular-loader"),
        // !isDevelopment
        //   ? require.resolve("angular/angular.min.js")
        //   :
        require.resolve("angular"),
      ],
      library: {
        type: "window",
      },
      dependOn: ["jquery"],
      layer: "ng-layer",
      chunkLoading: "import",
    },
    // "d3":{
    //   filename: "d3.[contenthash:8].js",
    //   import: [
    //     require.resolve("d3"),
    //   ],
    //   library: {
    //     type: "umd",
    //     umdNamedDefine: true,
    //   },
    // },
    "ng-module": {
      filename: "angular-module.[contenthash:8].js",
      import: [
        !isDevelopment
          ? require.resolve("angular-animate/angular-animate.min.js")
          : require.resolve("angular-animate"),
        !isDevelopment
          ? require.resolve("angular-aria/angular-aria.min.js")
          : require.resolve("angular-aria"),
        !isDevelopment
          ? require.resolve("angular-messages/angular-messages.min.js")
          : require.resolve("angular-messages"),
        !isDevelopment
          ? require.resolve("angular-resource/angular-resource.min.js")
          : require.resolve("angular-resource"),
        !isDevelopment
          ? require.resolve("angular-sanitize/angular-sanitize.min.js")
          : require.resolve("angular-sanitize"),
        !isDevelopment
          ? require.resolve("angular-touch/angular-touch.min.js")
          : require.resolve("angular-touch"),
        !isDevelopment
          ? require.resolve("angular-translate/dist/angular-translate.min.js")
          : require.resolve("angular-translate"),
      ],
      library: {
        type: "umd",
        umdNamedDefine: true,
      },
      dependOn: ["ng"],
      chunkLoading: "jsonp",
    },
    "ng-ui": {
      filename: "angular-ui-component.[contenthash:8].js",
      import: [
        // require.resolve("bootstrap"),
        require.resolve(
          isDevelopment
            ? "angular-ui-grid/ui-grid.js"
            : "angular-ui-grid/ui-grid.min.js",
        ),
        require.resolve(
          isDevelopment
            ? "angular-ui-scroll/dist/ui-scroll.js"
            : "angular-ui-scroll/dist/ui-scroll.min.js",
        ),
        require.resolve(
          isDevelopment
            ? "angular-ui-scroll/dist/ui-scroll-grid.js"
            : "angular-ui-scroll/dist/ui-scroll-grid.min.js",
        ),
      ],
      library: {
        type: "umd", // 'commonjs-static',
        // umdNamedDefine: true,
      },
      dependOn: ["ng"],
      chunkLoading: "jsonp",
    },
    "ng-uib": {
      filename: "angular-ui-bootstrap.[contenthash:8].js",
      import: [
        //  没有 min 版本
        require.resolve("angular-ui-bootstrap"),
      ],
      library: {
        type: "umd", // 'commonjs-static',
        // umdNamedDefine: true,
      },
      dependOn: ["ng"],
      chunkLoading: "jsonp",
    },
    // uirouter: {
    //   import: [
    //     require.resolve(
    //       "@uirouter/angularjs/release/angular-ui-router.min.js",
    //     ),
    //     require.resolve("@uirouter/core/_bundles/ui-router-core.min.js"),
    //   ],
    //   library: {
    //     type: "umd",
    //     umdNamedDefine: true,
    //   },
    //   dependOn: ["ng"],
    //   chunkLoading: "import",
    // },
    // echarts: {
    //   filename: "echarts.[contenthash].js",
    //   import: fg.sync("./node_modules/echarts/*.js"),
    //   library: {
    //     export: "default",
    //     type: "umd",
    //     umdNamedDefine: true,
    //     name: "echarts",
    //   },
    // },
    // "lit-component": {
    //   filename: "lit-component.[contenthash:8].js",
    //   import: [pwd2("./lit-comp/index.ts")],
    //   asyncChunks: true,
    //   chunkLoading: "import",
    // },
    // "echarts-core": {
    //   filename: "echarts-core.[contenthash:8].js",
    //   import: [require.resolve("echarts/core")],
    //   asyncChunks: true,
    //   chunkLoading: "import",
    // },
  },
  dotenv: {
    dir: __dirname,
  },
  recordsPath: path.join(__dirname, "records.json"),
  plugins: [
    new ManifestPlugin({
      entrypoints: true,
    }),
    preprocessorDirectives({}),
    // new AngularWebpackPlugin({
    //   tsconfig: "./tsconfig.app.json",

    //   // 其他配置选项...
    // }),
    WrapperProgressivePlugin(ProgressPlugin),
    // new DotenvRunPlugin({
    //   environment: process.env.NODE_ENV,
    //   files: [".env"], // 默认也会加载.env.local
    //   verbose: true,
    // }),
    new HtmlWebpackPlugin({
      template: "./index.html",
      // excludeChunks: ["ng", "jquery"],
    }),
    new HtmlWebpackPatchPlugin([
      [/* HTML */ /<!--\s+ONLY\s+FOR\s+PARCEL\s+-->/i, ""],
      [
        // eslint-disable-next-line regexp/no-super-linear-backtracking
        /* HTML */ /<script\s+type="module"\s+src="src\/index.mjs"\s*>\s*([\s\S]*?)\s*<\/script\s*>/i,
        /* HTML */ "<!-- HTML ENTRY LINE COMMENT BY PLUGIN 'HtmlRspackPatchPlugin' -->" +
          /* HTML */ '<!-- <script type="module" src="src/index.mjs"></script> -->',
      ],
    ]),
    turboConsole(),

    // new HtmlBundlerPlugin({
    //   entry: {
    //     index: "./index.html", // path to template file
    //   },
    // }),
  ].filter(Boolean),

  optimization: {
    minimize: false,
    removeEmptyChunks: true,
    runtimeChunk: "single",
    // // 内联依赖图, 移除未使用的导出
    // innerGraph: true,
    // // 合并模块 scope hoisting
    // concatenateModules: true,
    // // 导出名称压缩
    // mangleExports: "size",
    splitChunks: {
      // maxInitialRequests: 30,
      chunks: "initial",
      cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/i,
          priority: -50,
          chunks: "initial",
          reuseExistingChunk: true,
        },
        // jqModule: {
        //   test: /[\\/]jquery/i,
        //   priority: 0,
        //   chunks: "all",
        // },
        // ngModule: {
        //   test: /[\\/]angular(-loader)?[\\/]/i,
        //   priority: 0,
        //   chunks: "all",
        // },
        // prelude: {
        //   test: /[\\/]prelude[\\/]/i,
        //   priority: 0,
        //   chunks: "all",
        // },
        // hotClient: isDevelopment
        //   ? {
        //       test: /(dev-server[\\/]|[\\/]hot[\\/])/,
        //       priority: -20,
        //       chunks: "all",
        //     }
        //   : false,
        cssLoadRt: {
          name: "style-sheet-loader",
          test: /[\\/](css|style)-loader[\\/]/,
          priority: 0,
          chunks: "initial",
        },
        rxjs: {
          name: "rxjs-cache",
          test: /[\\/]node_modules[\\/]rxjs[\\/]/,
          priority: -30,
          chunks: "initial",
        },
        // ngxApp: {
        //   name: "ngx-app-cache",
        //   test: /[\\/]ngx-app[\\/]/i,
        //   priority: 0,
        //   chunks: "all",
        // },
      },
    },
  },

  output: {
    clean: true,
    environment: {
      arrowFunction: true,
    },
    // publicPath: "./public",
    filename: "[name].[contenthash:8].js",
    assetModuleFilename: "assets/[name]-[contenthash:8][ext][query]",
    chunkFilename: "chunks/[name]-[contenthash:8].js",
    uniqueName: "ngV1_app",
    hotUpdateChunkFilename: "[id]~[fullhash].hot-update.js",
    hotUpdateMainFilename: "[runtime]~[fullhash].hot-update.json",
  },
  module: defineLoaderRuleSetRule(),
};

/**
 * @returns {import("webpack").RuleSetRule}
 */
function defineLoaderRuleSetRule() {
  return {
    parser: {
      // // for css_module
      // "css/auto": {
      //   namedExports: false,
      // },
      // "css/module": {
      //   namedExports: false,
      // },
    },
    // generator: {
    //   asset: {
    //     filename: "asset#[name]-[contenthash:8][ext][query]",
    //   },
    // },
    rules: [
      {
        // # typescript section -- load lit-component
        test: /\.tsx?$/i,
        // resolve: {
        //   alias: {
        //     angular: isDevelopment
        //       ? pwd2("./node_modules/angular/angular.js")
        //       : pwd2("./node_modules/angular/angular.min.js"),
        //     "angular-loader": isDevelopment
        //       ? pwd2("./node_modules/angular-loader/angular-loader.js")
        //       : pwd2("./node_modules/angular-loader/angular-loader.min.js"),
        //   },
        // },
        oneOf: [
          // {
          //   test: /\.(module|service|component)\.ts$/i,
          //   use: [
          //     {
          //       loader: "@ngtools/webpack",
          //     },
          //   ],
          // },
          {
            // exclude: /\.ts$/i,
            use: [
              {
                loader: "@swc-node/loader",
                options: /** @type {import("@swc-node/loader").Options} */ ({
                  compilerOptions: {
                    experimentalDecorators: true,
                    emitDecoratorMetadata: true,
                    useDefineForClassFields: false,
                  },
                  configFile: pwd2("./lit-comp/tsconfig.json"),
                }),
                // /** @type {import("@rspack/core").SwcLoaderOptions} */ ({
                //   jsc: {
                //     baseUrl: pwd2("."),
                //     target: "es2022",
                //     parser: {
                //       syntax: "typescript",
                //       decorators: true,
                //     },
                //     transform: {
                //       decoratorMetadata: true,
                //     },
                //   },
                //   module: {
                //     type: "es6",
                //   },
                //   isModule: true,
                // }),
              },
            ],
          },
        ],
      },
      // # javascript section
      // {
      //   test: /\.(m?js|jsx)$/i,
      //   //  /i 快大概 10%, 只是匹配的速度不会超过0.050ms [1586项(纯数组匹配): 0.056 -> 0.050ms]
      //   exclude: /node_modules/,
      //   loader: "swc-loader",
      //   options: /** @type {import("@rspack/core").SwcLoaderOptions} */ ({
      //     jsc: {
      //       baseUrl: pwd2("."),
      //       parser: {
      //         syntax: "ecmascript",
      //       },
      //       target: "es2022",
      //     },
      //     module: {
      //       type: "es6",
      //     },
      //     isModule: true,
      //   }),
      // },

      // # HTML section
      {
        test: /\.html$/i,
        loader: "html-loader",
        options: {
          // preprocessor: require("./html-preprocessor.cjs").insertDataInspect
        },
      },
      // css section
      {
        test: /(\.module)?\.(le|p?c)ss$/i,
        oneOf: [
          {
            test: /\.module\.css/,
            // type: "javascript/auto",
            use: [
              {
                loader: "style-loader",
                // todo:
                options: /** @type {import("css-loader").Options} */ ({}),
              },
              {
                loader: "css-loader",
                options: {
                  modules: true,
                },
              },
            ],
          },
          {
            test: /\.css$/i,
            exclude: /\.module\.css/i,
            // type: "css/auto",
            use: [
              {
                loader: "style-loader",
                // todo:
                options: /** @type {import("style-loader").Options} */ ({}),
              },
              {
                loader: "css-loader",
                options: /** @type {import("css-loader").Options} */ ({}),
              },
            ],
          },
          {
            test: /\.less$/i,
            // type: "css/auto",
            use: [
              "style-loader",
              "css-loader",
              {
                loader: "less-loader",
                options: /**
                 * @import less from 'less'
                 * @type {Less.Options}
                 */ (
                  {
                    // globalVars: {
                    //   // add your global variables here
                    //   primaryColor: "#007bff",
                    // },
                  }
                ),
              },
            ],
            // set to 'css/auto' if you want to support '*.module.less' as CSS Modules, otherwise set type to 'css'
          },
          {
            test: /\.pcss$/i,
            // type: "css/auto",
            // type: "javascript/auto",
            use: [
              // "style-loader",
              {
                // CSSStyleSheet
                loader: "css-loader",
                options: {
                  exportType: "css-style-sheet",
                },
              },
              {
                loader: "postcss-loader",
                options: {
                  postcssOptions: {
                    plugins: {
                      "@tailwindcss/postcss": {},
                    },
                  },
                },
              },
            ],
          },
        ],
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: "asset/resource",
      },
      {
        test: /\.png$/,
        loader: ImageMinimizerPlugin.loader,
        type: "asset/resource",
      },
    ],
  };
}
